package com.vito.oa.act.service.impl;

import java.text.MessageFormat;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;

import com.alibaba.dubbo.config.annotation.Service;
import com.vito.act.tool.ActivitiContants;
import com.vito.act.tool.ScriptToolInterface;
import com.vito.base.authoriza.model.RoleModel;
import com.vito.base.util.StringUtil;
import com.vito.base.util.Validata;
import com.vito.oa.act.constant.OaActContants;
import com.vito.oa.act.dao.ActUserProcessSettingMapper;
import com.vito.oa.act.dao.OaActApproverMapper;
import com.vito.oa.act.model.ActUserProcessSettingModel;
import com.vito.oa.act.service.OaActApproverServer;

@Service
public class OaActApproversServerImlp implements OaActApproverServer {
	private static final String act_users = "users";// 审批人列表
	private static final String director_dept_id = "directorDeptId";// 当前流转主管所在部门
	private static final String prev_user = "prevUser";// 前一级审批人ID
	private static final String user_type = "userType";
	private static final String type_id = "typeId";
	private static final String node_name = "nodeName";
	private static final String node_id = "nodeId";
//	private static final boolean skipEmptyNode = Boolean
//			.parseBoolean(StringUtil.getProperties("conf/sysConfig", "skipemptynode"));

	@Autowired
	private OaActApproverMapper oaActApproverMapper;
	@Autowired
	private ActUserProcessSettingMapper actUserProcessSettingMapper;

	@Override
	public int queryDefinedApproversCount(String processKey, String topDeptId) {
		return oaActApproverMapper.queryDefinedApproverCount(processKey, topDeptId);
	}

	@Override
	public int queryBranchCount(String processKey, String topDeptId) {
		return oaActApproverMapper.querybranchCount(processKey, topDeptId);
	}

	@Override
	public String queryProcessBranch(String processKey, String topDeptId, String des) {
		String branchId = "";
		List<Map<String, String>> branchList = oaActApproverMapper.queryProcessBranchList(processKey, topDeptId);
		if (des == null) {
			Map<String, String> branch = branchList.get(0);
			branchId = branch.get("branchId");
		} else {
			for (Map<String, String> branch : branchList) {
				String vaid = branch.get("branchVaId");
				if ((!StringUtil.isEmpty(des)) && !"null".equals(des)) {
					String exp = branch.get("branchExp").replace(vaid, "0");
					exp = MessageFormat.format(exp, des);
					// 表达式为true则按照设置的流程处理人走
					if ((boolean) ScriptToolInterface.getScriptToolInterface().runCode(exp)) {
						branchId = branch.get("branchId");
						break;
					}
				}
			}
		}
		return branchId;
	}

	@Override
	public Map<String, Object> queryDefinedApprovers(String key, String userId, String deptId, String companyId) {
		if (key != null && userId != null && deptId != null && companyId != null) {
			return getApprovers(key, userId, deptId, companyId, null);
		}
		return null;
	}

	@Override
	public Map<String, Object> queryDefinedApprovers(String key, String userId, String deptId, String companyId,
			String branchId) {
		if (key != null && userId != null && deptId != null && companyId != null && branchId != null) {
			return getApprovers(key, userId, deptId, companyId, branchId);
		}
		return null;
	}
	private Map<String, Object> getApprovers(String key, String userId, String deptId, String companyId,
			String branchId) {

		Map<String, Object> result = null;
		List<Map<String, String>> definedList = null;
		if (branchId == null) {
			definedList = oaActApproverMapper.queryDefinedApproverList(key, companyId);
		} else {
			definedList = oaActApproverMapper.queryBranchApproverList(key, branchId,companyId);
		}

		if (definedList != null) {
			int index = 0;
			result = new HashMap<String, Object>();
			LinkedList<Map<String, Object>> approverList = new LinkedList<>();
			ActUserProcessSettingModel setting = actUserProcessSettingMapper.queryUserProcessSetting(key, companyId);
			boolean distinct = setting.getDistinct() == 1;
			String currentDept = deptId;
			String[] currentUser = userId.split(OaActContants.SEPARATOR);
			Map<String, Object> user = null;
			for (Map<String, String> defined : definedList) {
				user = getUserByType(defined, companyId, currentDept, currentUser, userId, distinct);
				currentUser = (String[]) user.get(prev_user);
				currentDept = (String) user.get(director_dept_id);
				user.remove(prev_user);
			/*	user.remove(director_dept_id);兼容ios旧版本需要*/
				if (user.containsKey(act_users)) {
					user.put("userType", defined.get(user_type));
//					if (true == skipEmptyNode || true == distinct) {
//						user.put("nodeId", definedList.get(index).get(node_id));
//						user.put("nodeName", definedList.get(index).get(node_name));
//					} else {
//						user.put("nodeId", defined.get(node_id));
//						user.put("nodeName", defined.get(node_name));
//					}
					user.put("nodeId", defined.get(node_id));
					user.put("nodeName", defined.get(node_name));
					user.put("orderNum", ++index);
					approverList.add(user);
				} else {
					continue;
				}
			}
			result.put("approvers", approverList);
			result.put("distinct", distinct);
		}
		return result;
	}

	/**
	 * 
	 * @param defined
	 *            审批人配置
	 * @param companyId
	 *            企业ID
	 * @param directorDept
	 *            当前主管部门
	 * @param prevUser
	 *            前一级的审批人
	 * @param startUserId
	 *            发起人
	 * @return
	 */
	private Map<String, Object> getUserByType(Map<String, String> defined, String companyId, String directorDept,
			String[] prevUser, String startUserId, boolean distinct) {
		Map<String, Object> nodeUser = new HashMap<String, Object>();
		String nextUserId = null;
		String nextUserType = defined.get(user_type);
		String currentTypeId = defined.get(type_id);
		String directorDeptIdTemp = directorDept;
		nodeUser.put(director_dept_id, directorDeptIdTemp);
		nodeUser.put(prev_user, prevUser);

		if (ActivitiContants.PROCESS_USER_TYPE_USERID.equals(nextUserType)) {
			nextUserId = currentTypeId;

		} else if (ActivitiContants.PROCESS_USER_TYPE_DEPTID.equals(nextUserType)) {
			nextUserId = oaActApproverMapper.queryDeptLeaderByDeptId(currentTypeId);
			String deptName = oaActApproverMapper.queryDeptNameById(currentTypeId);
			nodeUser.put("deptName", deptName);
		} else if (ActivitiContants.PROCESS_USER_TYPE_DIRECTOR.equals(nextUserType)) {
			Map<String, String> leader = queryDeptDirector(directorDeptIdTemp);
			nextUserId = leader.get("directorId");
			String nextDirectorDept = leader.get("nextDirectorDept");
			nodeUser.put(director_dept_id, nextDirectorDept);
			// 如果是主管自己发起审批，则他的一级主管是他父级部门的主管。
			if (startUserId.equals(nextUserId)) {
				return getUserByType(defined, companyId, nextDirectorDept, prevUser, startUserId, distinct);
			}
		} else if (ActivitiContants.PROCESS_USER_TYPE_ROLEID.equals(nextUserType)) {
			// List<Map<String, String>> approvers =
			// oaActApproverMapper.queryUserByRole(currentTypeId);
			List<Map<String, String>> approvers = queryRoleUsers(companyId, directorDept, currentTypeId);
			if (approvers != null && !approvers.isEmpty()) {
				String roleName = oaActApproverMapper.queryRoleNameById(currentTypeId);
				nodeUser.put("roleName", roleName);
				nodeUser.put(act_users, approvers);
				nodeUser.put(prev_user, null);// 按职务审批的下一个节点不考虑去重
			}
		}

		if (Validata.notNullOrEmpty(nextUserId)) {
			String[] users = nextUserId.split(OaActContants.SEPARATOR);
			if (distinct) {
				// 与上级审批人比较，过滤掉重复人
				users = filterRepeat(users, prevUser);
			} else {
				users = filterRepeat(users, null);
			}

			if (users.length > 0) {
				List<Map<String, String>> approvers = oaActApproverMapper.queryUserInfoById(users);
				if (approvers != null && !approvers.isEmpty()) {
					nodeUser.put(act_users, approvers);
					nodeUser.put(prev_user, users);
				}
			}
		}

		return nodeUser;
	}

	/**
	 * 过滤掉已经存在的数据
	 * 
	 * @param data
	 * @param exist
	 * @return
	 */
	private String[] filterRepeat(String[] data, String[] exist) {
		Set<String> dataSet = new HashSet<>();
		if (data != null) {
			for (String item : data) {
				dataSet.add(item);
			}
			if (exist != null) {
				List<String> compare = Arrays.asList(exist);
				Iterator<String> it = dataSet.iterator();
				while (it.hasNext()) {
					if (compare.contains(it.next())) {
						it.remove();
					}
				}
			}
		}
		return dataSet.toArray(new String[dataSet.size()]);
	}

	// 查找角色审批人
	private List<Map<String, String>> queryRoleUsers(String topDeptId, String directorDeptId, String roleId) {
		String roleRange = oaActApproverMapper.queryCompanyRoleRange(topDeptId);

		List<Map<String, String>> approvers = oaActApproverMapper.queryUserByRole(roleId);
		if (null == approvers || 0 == approvers.size()) {
			return null;
		}
		if (StringUtil.isEmpty(roleRange)) {
			return approvers;
		}
		List<Map<String, String>> resultList = approvers;
		final int length = roleRange.length();
		int index = 0;
		int iRoleRange = -1;
		while (index < length) {
			String inxString = roleRange.substring(index, ++index);
			try {
				int temproleRange = Integer.parseInt(inxString);
				if (iRoleRange >= temproleRange) {
					continue; // 先查找的是大范围的角色，再查找的是小范围的角色
				}
				if (OaActContants.PROCESS_ROLERANGE_COMPANY == temproleRange) {
					iRoleRange = temproleRange;
					continue;
				}
				iRoleRange = temproleRange;
				List<Map<String, String>> rList = getRoleUsersByRoleRange(approvers, topDeptId, directorDeptId, roleId,
						iRoleRange);
				if (null != rList && 0 < rList.size()) {
					resultList = rList;
					break;
				}
			} catch (NumberFormatException e) {
				return resultList;
			}
		}

		return resultList;
	}

	private List<Map<String, String>> getRoleUsersByRoleRange(final List<Map<String, String>> approvers,
			final String topDeptId, String directorDeptId, final String roleId, final int roleRange) {
		switch (roleRange) {
		case OaActContants.PROCESS_ROLERANGE_DEPT:
			return oaActApproverMapper.queryRoleUserInDept(approvers, directorDeptId);
		case OaActContants.PROCESS_ROLERANGE_DIRECTDEPT:
			return oaActApproverMapper.queryRoleUserInDirectDept(approvers, directorDeptId);
		case OaActContants.PROCESS_ROLERANGE_COMPANY:
		default:
			return approvers;
		}
	}

	// 查询部门主管，没有则递归找上级部门主管，一直找到为止并返回，没有返回null；
	private Map<String, String> queryDeptDirector(String deptId) {
		Map<String, String> leader = new HashMap<String, String>();
		String directorId = oaActApproverMapper.queryDeptLeaderByDeptId(deptId);
		String nextDirectorDeptId = oaActApproverMapper.queryParentDeptId(deptId);
		// if(Validata.isNullOrEmpty(directorId)){
		// if(Validata.notNullOrEmpty(nextDirectorDeptId)){
		// return queryParentDeptleader(nextDirectorDeptId);
		// }
		// }
		leader.put("directorId", directorId);
		leader.put("nextDirectorDept", nextDirectorDeptId);
		return leader;
	}

	@Override
	public List<Map<String, String>> queryProcessBranchList(String processKey, String topDeptId) {
		return oaActApproverMapper.queryProcessBranchList(processKey, topDeptId);
	}

	@Override
	public List<Map<String, String>> queryProcessAllNode(String processKey,String companyId) {
		return oaActApproverMapper.queryProcessAllNode(processKey,companyId);
	}

	@Override
	public List<RoleModel> queryRoleByDept(Map<String, Object> param) {
		return oaActApproverMapper.queryRoleByDept(param);
	}

	@Override
	public Map<String, String> queryNextNode(String processKey, String currentNodeId) {
		return oaActApproverMapper.queryNextNode(processKey, currentNodeId);
	}
	
}
